<!DOCTYPE html>
<html lang="zh-CH" >
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="author" content="" />
	
	
	
	<title>基于HeadFirst设计模式之装饰者模式 ｜ zansimple</title>
	
    
    
    <meta name="description" content="想必大家都知道面向对象编程中继承的好处，也知道继承在某些需求上能发挥很大的作用。但是滥用继承关系会造成：类爆炸，设计死板，基类加入的新功能不适用于所有子类等问题。所以大家要慎用。下面这个设计模式只用简单的继承是完不成我们想要的需求的,我们应该使用组合来是系统更有弹性并且易于维护。
开放-关闭原则： 类应该对扩展开放，对修改关闭初识装饰者模式 例：星巴兹是以狂战速度最快而闻名的咖啡连锁店。因为扩张速度实在太快，他们最北更新订单系统，以合乎他们的饮料供应要求。
咖啡类型： DarkRoast ，HouseBlend , Espresso , Decaf 。
调料：Milk , Mocha , Soy , Whip 。
定义装饰者模式 动态的将责任附加到对象上。若要扩展功能，装饰者提供了比继承更有弹性的替代方案。 想法：  装饰者和被装饰者对象有相同的超类型。 可以用一个或多个装饰者包装一个对象。 几人装饰者和被装饰者对象有相同的超类型，所有在任何需要原始对象的场合，可以用装饰过的对象代替它。 装饰者可以在所委托被装饰者的行为之前或之后，加上自己的行为，以达到特定的目的。 对象可以在任何时候被装饰，所以可以在运行的时候动态地，不限量的用你喜欢的装饰者来装饰对象。  下面是装饰者模式的类图
例子的解决方案 用装饰者完成饮料模型的类图 然后我们写下星巴兹的代码 首先是Beverage类：
public abstract class Beverage{string description = &amp;quot;UnKnow Beverage&amp;quot;;public string GetDescription(){return description;}public abstract double Cost();} 然后实现调料的抽象类，也就是装饰者类：
//首先必须让CondimentDecorator能够代替Beverage ,所以讲此类继承自Beveragepublic abstract class CondimentDecorator : Beverage{//所有的调料必须重写GetDescription方法。public abstract string GetDescription();}  下面是饮料的代码：" />
    

    

	
    
    <link rel="shortcut icon" href="https://lenzan.github.io/images/favicon.ico" />

    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/normalize.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/zozo.css" />
	<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/highlight.css" />

    
    
</head>

<body>
    <div class="main animate__animated animate__fadeInDown">
        <div class="nav_container animated fadeInDown">
    <div class="site_nav" id="site_nav">
        <ul>
            
            <li>
                <a href="/">首页</a>
            </li>
            
            <li>
                <a href="/">unity</a>
            </li>
            
            <li>
                <a href="/">归档</a>
            </li>
            
            <li>
                <a href="/">关于</a>
            </li>
            
        </ul>
    </div>
    <div class="menu_icon">
        <a id="menu_icon"><i class="ri-menu-line"></i></a>
    </div>
</div>
        <div class="header animated fadeInDown">
    <div class="site_title_container">
        <div class="site_title">
            <h1>
                <a href="https://lenzan.github.io/">
                    <span>zansimple</span>
                    <img src="https://lenzan.github.io/images/logo.svg" />
                </a>
            </h1>
        </div>
        <div class="description">
            <p class="sub_title">专注于Unity虚拟现实开发，游戏开发</p>
            <div class="my_socials">
                
                <a href="https://lenzan.github.io/index.xml" type="application/rss+xml" title="rss" target="_blank"><i
                        class="ri-rss-fill"></i></a>
            </div>
        </div>
    </div>
</div>
        <div class="content">
            <div class="post_page">
                <div class="post animate__animated animate__fadeInDown">
                    <div class="post_title post_detail_title">
                        <h2><a href='/posts/design/HeadFirst-garnisher/'>基于HeadFirst设计模式之装饰者模式</a></h2>
                        <span class="date">2018.06.14</span>
                    </div>
                    <div class="post_content markdown"><!-- raw HTML omitted -->
<p>想必大家都知道面向对象编程中继承的好处，也知道继承在某些需求上能发挥很大的作用。但是滥用继承关系会造成：类爆炸，设计死板，基类加入的新功能不适用于所有子类等问题。所以大家要慎用。下面这个设计模式只用简单的继承是完不成我们想要的需求的,我们应该使用组合来是系统更有弹性并且易于维护。</p>
<h3 id="开放-关闭原则">开放-关闭原则：</h3>
<p><!-- raw HTML omitted -->类应该对扩展开放，对修改关闭<!-- raw HTML omitted --></p>
<h3 id="初识装饰者模式">初识装饰者模式</h3>
<p>例：星巴兹是以狂战速度最快而闻名的咖啡连锁店。因为扩张速度实在太快，他们最北更新订单系统，以合乎他们的饮料供应要求。<br>
咖啡类型： DarkRoast ，HouseBlend , Espresso , Decaf 。<br>
调料：Milk , Mocha , Soy , Whip 。</p>
<h4 id="定义装饰者模式">定义装饰者模式</h4>
<pre><code>动态的将责任附加到对象上。若要扩展功能，装饰者提供了比继承更有弹性的替代方案。
</code></pre>
<h4 id="想法">想法：</h4>
<ul>
<li>装饰者和被装饰者对象有相同的超类型。</li>
<li>可以用一个或多个装饰者包装一个对象。</li>
<li>几人装饰者和被装饰者对象有相同的超类型，所有在任何需要原始对象的场合，可以用装饰过的对象代替它。</li>
<li><!-- raw HTML omitted -->装饰者可以在所委托被装饰者的行为之前或之后，加上自己的行为，以达到特定的目的。<!-- raw HTML omitted --></li>
<li>对象可以在任何时候被装饰，所以可以在运行的时候动态地，不限量的用你喜欢的装饰者来装饰对象。</li>
</ul>
<p>下面是装饰者模式的类图<br>
<img src="/img/garnisher/garnisher.png" alt="avatar"></p>
<h4 id="例子的解决方案">例子的解决方案</h4>
<h5 id="用装饰者完成饮料模型的类图">用装饰者完成饮料模型的类图</h5>
<p><img src="/img/garnisher/beverage.png" alt="avatar"></p>
<h5 id="然后我们写下星巴兹的代码">然后我们写下星巴兹的代码</h5>
<p>首先是Beverage类：</p>
<pre><code>public abstract class Beverage
{
    string description = &quot;UnKnow Beverage&quot;;
    public string GetDescription()
    {
        return description;
    }
    public abstract double Cost();
}
</code></pre>
<p>然后实现调料的抽象类，也就是装饰者类：</p>
<pre><code>//首先必须让CondimentDecorator能够代替Beverage ,所以讲此类继承自Beverage
public abstract class CondimentDecorator : Beverage
{
    //所有的调料必须重写GetDescription方法。
    public abstract string GetDescription();
} 
</code></pre>
<p>下面是饮料的代码：</p>
<pre><code>public class Espresso : Beverage
{

    public Espresso()
    { 
        description=&quot;Espresso&quot;; 
    }

    public double Cost()
    {
        return 1.99;
    }
}

public class HouseBlend : Beverage
{
    
    public HouseBlend()
    { 
        description=&quot;HouseBlend&quot;; 
    }

    public double Cost()
    {
        return 0.89;
    }
}

public class DarkRoast : Beverage
{
    
    public DarkRoast()
    { 
        description=&quot;DarkRoast&quot;; 
    }

    public double Cost()
    {
        return 0.99;
    }
}

public class Decaf : Beverage
{
    
    public Decaf()
    { 
        description=&quot;Decaf&quot;; 
    }

    public double Cost()
    {
        return 1.05;
    }
}
</code></pre>
<p>然后是调料的代码：</p>
<pre><code>public class Mocha : CondimentDecorator
{
    Beverage beverage;
    public Mocha(Beverage beverage)
    { 
       this.beverage = beverage;  
    }
    public string GetDescription()
    {
        return beverage.GetDescription() + &quot;,Mocha&quot;;
    }
    public double Cost()
    {
        return 0.20 + beverage.Cost();
    }
}

public class Soy : CondimentDecorator
{
    Beverage beverage;
    public Soy(Beverage beverage)
    { 
       this.beverage = beverage;  
    }
    public string GetDescription()
    {
        return beverage.GetDescription() + &quot;,Soy&quot;;
    }
    public double Cost()
    {
        return 0.15 + beverage.Cost();
    }
}

public class Whip : CondimentDecorator
{
    Beverage beverage;
    public Whip(Beverage beverage)
    { 
       this.beverage = beverage;  
    }
    public string GetDescription()
    {
        return beverage.GetDescription() + &quot;,Whip&quot;;
    }
    public double Cost()
    {
        return 0.10 + beverage.Cost();
    }
}

public class Milk : CondimentDecorator
{
    Beverage beverage;
    public Milk(Beverage beverage)
    { 
       this.beverage = beverage;  
    }
    public string GetDescription()
    {
        return beverage.GetDescription() + &quot;,Milk&quot;;
    }
    public double Cost()
    {
        return 0.15 + beverage.Cost();
    }
}
</code></pre>
<p>剩下的就是测试代码了：</p>
<pre><code>public static class Main(string args[])
{
    Beverage beverage = new Espresso();
    beverage = new Mocha(beverage);
    beverage = new Whip(beverage);
    Console.WriteLine(beverage.GetDescription() + &quot;$&quot; + beverage.Cost());
}
</code></pre>
<p>装饰者有能力为设计注入弹性，但是也有不好的地方，有时候会在设计中加入大量的小类，会导致别人不容易了解我的设计方式。<br>
采用装饰者在实例化组件时，将增加代码的复杂度，一旦使用装饰者模式，不只需要实例化组件，还要把此组件包装进装饰者中，天知道有多少个。</p>
</div>
                    <div class="post_footer">
                        
                        <div class="meta">
                            <div class="info">
                                <span class="field tags">
                                    <i class="ri-stack-line"></i>
                                    
                                    <a href="https://lenzan.github.io/tags/%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F/">装饰者模式</a>
                                    
                                    <a href="https://lenzan.github.io/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
                                    
                                </span>
                            </div>
                        </div>
                        
                    </div>
                </div>
                
                
            </div>
        </div>
    </div>
    <a id="back_to_top" href="#" class="back_to_top"><span>△</span></a>
    <footer class="footer">
    <div class="powered_by">
        <a href="https://varkai.com">Designed by VarKai,</a>
        <a href="http://www.gohugo.io/">Proudly published with Hugo</a>
    </div>

    <div class="footer_slogan">
        <span></span>
    </div>
</footer>
    <script src="https://lenzan.github.io/js/jquery-3.5.1.min.js"></script>
<link href="https://lenzan.github.io/css/fancybox.min.css" rel="stylesheet">
<script src="https://lenzan.github.io/js/fancybox.min.js"></script>
<script src="https://lenzan.github.io/js/zozo.js"></script>






</body>

</html>